package com.gupao.vip.mic.javaapi;

import java.io.IOException;
import java.util.List;
import java.util.Random;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;

public class DistributeLock {

	ZooKeeper zooKeeper;
	private int sessionTimeout;
	private String createNode;
	final public static String ROOT_LOCLS="/LOCKS";
	private CountDownLatch countDownLatch=new CountDownLatch(1);
	
	
	public DistributeLock() throws IOException, InterruptedException{
		zooKeeper=ZookeeperClientUtils.getInstance();
		sessionTimeout=ZookeeperClientUtils.sessionTimeout;
	}
	public Boolean lock() throws KeeperException, InterruptedException{
		/**
		 * 1 创建子节点
		 * 2 判断刚创建节点是不是已存在的节点中排在第一个的，若是，删除
		 * 若不是添加删除的监听事件
		 */
		/**
		 * zooKeeper.create(
		 */
		/*zooKeeper.create(final String path, byte data[], List<ACL> acl,
	            CreateMode createMode)*/
	    createNode = zooKeeper.create(ROOT_LOCLS+"/", "123".getBytes(), 
	    		ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);
		System.out.println("线程"+Thread.currentThread().getName()+"创建了节点["+createNode+"]");
		List<String> childrens = zooKeeper.getChildren(ROOT_LOCLS, true);
		SortedSet<String> nodes=new TreeSet<String>();
		for (String children : childrens) {
			nodes.add(ROOT_LOCLS+"/"+children);
		}
		String first = nodes.first();
		if (createNode.equals(first)){
			System.out.println("线程"+Thread.currentThread().getName()+" 成功获取锁["+createNode+"]");
			return true;
		}else{ 
			SortedSet<String> lessthanNodes = nodes.headSet(createNode);
			if(!lessthanNodes.isEmpty()){
				String lastNode = lessthanNodes.last();
				System.out.println("lessthanNodes的长度："+lessthanNodes.size());
				zooKeeper.exists(lastNode, new LockWatch(countDownLatch));
				countDownLatch.await(sessionTimeout, TimeUnit.MILLISECONDS);
				System.out.println(Thread.currentThread().getName()+" 成功获取锁["+createNode+"]");
				return true;
			}
		}
		return false;
		 
	}
	
	public Boolean unlock() throws InterruptedException, KeeperException{
		System.out.println("线程"+Thread.currentThread().getName()+"->开始释放锁，["+createNode+"]");
		zooKeeper.delete(createNode, -1);
		return true;
	}
	
	public static void main(String[] args) throws IOException, InterruptedException {
		final CountDownLatch countDownLatch=new CountDownLatch(10);
		final Random random=new Random();
		for (int i = 0; i <10; i++) {
			new Thread(new Runnable() {
				public void run() {
					DistributeLock lock =null;
					try {
						lock =new DistributeLock();
						countDownLatch.countDown();
						countDownLatch.await();
						lock.lock();
						Thread.sleep(random.nextInt(500));
					} catch (Exception e) {
						e.printStackTrace();
					}finally{
						if(lock!=null){
							try {
								lock.unlock();
							} catch (Exception e) {
							}
						}
					}
					
					
					
				}
			}).start();
			
		}
	}
}
